package com.app.system.permission.web.permission;

import com.app.log.annotation.MyLog;
import com.app.system.common.EncipherPwd;
import com.app.system.jpa.PageBean;
import com.app.system.permission.model.Department;
import com.app.system.permission.model.SysRole;
import com.app.system.permission.model.UserInfo;
import com.app.system.permission.service.SysRoleService;
import com.app.system.permission.service.UserInfoService;
import com.app.system.utils.CollectionUtils;
import com.app.system.utils.ParamUtils;
import com.app.system.utils.base64.Base64Utils;
import com.app.system.utils.exception.AjaxException;
import com.app.system.utils.exception.Precondition;
import com.app.system.utils.exception.Response;
import com.app.system.utils.page.LayUiUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.session.Session;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Created by wcf-pc on 2018/6/2.
 */
@Controller
@RequestMapping("/permission/userInfo/*")
@SuppressWarnings("all")
public class UserInfoController {

    @Resource
    private UserInfoService userInfoService;
    @Resource
    private SysRoleService sysRoleService;
    @Resource
    private EncipherPwd encipherPwd;

    @RequestMapping("list")
    @RequiresPermissions("userInfo:list")
    public void list(ModelMap modelMap) {
        List<SysRole> sysRoleList = this.sysRoleService.findAll();
        modelMap.addAttribute("sysRoleList", sysRoleList);
    }

    private String getRoleNames(Set<SysRole> set) {
        StringBuffer sb = new StringBuffer("");
        if (CollectionUtils.isNotEmpty(set)) {
            for (SysRole sysRole : set) {
                if (sb.length() > 0) {
                    sb.append("、");
                }
                sb.append(sysRole.getRole());
            }
        }
        return sb.toString();
    }

    @RequestMapping("loadData")
    @ResponseBody
    @RequiresPermissions("userInfo:loadData")
    public Map loadData(HttpServletRequest request) {
        List<Map> listData = Lists.newArrayList();
        PageBean<UserInfo> pageList = this.userInfoService.findPageBean();
        List<UserInfo> datas = pageList.getDatas();
        if (CollectionUtils.isNotEmpty(datas)) {
            Map<String, Object> item = null;
            for (UserInfo u : datas) {
                item = null;
                item = Maps.newHashMap();
                item.put("id", u.getId());
                item.put("departmentName", u.getDepartment() == null ? "" : u.getDepartment().getName());
                item.put("username", u.getUsername());
                item.put("name", u.getName());
                item.put("roles", getRoleNames(u.getRoleList()));
                item.put("state", Integer.valueOf(u.getState()));

                listData.add(item);
            }
        }
        return LayUiUtils.page(pageList.getTotalCount().intValue(), listData);
    }

    @RequestMapping("form")
    @RequiresPermissions("userInfo:form")
    public void form(HttpServletRequest request, ModelMap model) {
        int id = ParamUtils.getInt(request, "id", 0);
        UserInfo userInfo = this.userInfoService.findOneById(id);
        if (userInfo == null) {
            userInfo = new UserInfo();
        }
        model.addAttribute("userInfo", userInfo);

        Set<SysRole> userRoleSet = userInfo.getRoleList();
        List<Integer> roleIds = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(userRoleSet)) {
            for (SysRole sysRole : userRoleSet) {
                roleIds.add(sysRole.getId());
            }
        }
        model.addAttribute("roleIds", roleIds);

        List<SysRole> sysRoleList = this.sysRoleService.findAll();
        model.addAttribute("sysRoleList", sysRoleList);
    }

    @MyLog(value = "用户信息保存")
    @RequestMapping("save")
    @ResponseBody
    @RequiresPermissions("userInfo:save")
    public synchronized Response save(HttpServletRequest request) throws AjaxException {
        int id = ParamUtils.getInt(request, "id", 0);
        UserInfo userInfo = this.userInfoService.findOneById(id);
        if (userInfo == null) {
            userInfo = new UserInfo();
        } else {
//            UserInfo loginUser = this.userInfoService.findByUsername(new WebUtils().getLoginUserName());
//            Integer loginLeavel = loginUser.getLeavel();
//            loginLeavel = loginLeavel == null ? 0 : loginLeavel;
//
//            Integer leavel = userInfo.getLeavel();
//            loginLeavel = leavel == null ? 0 : leavel;
//            String username = userInfo.getUsername();
//
//            if (!username.equals(loginUser.getUsername()) && loginLeavel <= leavel) {
//                return new Response("9999", "无权限修改该用户的信息");
//            }
        }
        ServletRequestDataBinder binder = new ServletRequestDataBinder(userInfo);
        binder.bind(request);

        int[] roles = ParamUtils.getIntParameters(request, "role");
        Set<SysRole> sysRoleList = Sets.newHashSet();
        if (roles != null && roles.length > 0) {
            for (int r : roles) {
                SysRole sysRole = new SysRole();
                sysRole.setId(r);
                sysRoleList.add(sysRole);
            }
        }
        userInfo.setRoleList(sysRoleList);
        int departmentId = ParamUtils.getInt(request, "departmentId", 0);
        if (departmentId > 0) {
            Department department = new Department();
            department.setId(departmentId);
            userInfo.setDepartment(department);
        }
        this.userInfoService.saveBeforeValidateUserName(userInfo);

        return new Response("0001", "保存成功");
    }

    @MyLog(value = "用户信息删除")
    @RequestMapping("delById")
    @ResponseBody
    @RequiresPermissions("userInfo:delById")
    public Response delById(HttpServletRequest request) {
        String ids = ParamUtils.getString(request, "ids", "");
        if (ids != null && ids.length() > 0) {
            String[] idsArray = ids.split(",");
            List<Integer> idsLists = Lists.newArrayList();
            for (String id : idsArray) {
                idsLists.add(Integer.valueOf(id));
            }
            this.userInfoService.delByIds(idsLists);
        }
        return new Response("0001", "删除成功");
    }

    @MyLog(value = "用户状态设置")
    @RequestMapping("setState")
    @ResponseBody
    @RequiresPermissions("userInfo:setState")
    public Response setState(HttpServletRequest request) {
        Integer id = ParamUtils.getInt(request, "id", 0);
        Integer state = ParamUtils.getInt(request, "state", 0);
        UserInfo userInfo = this.userInfoService.findOneById(id);
        Precondition.checkAjaxArguement(userInfo != null, "1111", "无效操作");
        userInfo.setState(state);
        this.userInfoService.save(userInfo);
        return new Response("0001", "更新成功");
    }

    @RequestMapping(value = "pwdForm")
    @RequiresPermissions("userInfo:pwdForm")
    public void pwdForm(HttpServletRequest request, int id, ModelMap model) {
        UserInfo userInfo = this.userInfoService.findOneById(id);
        Precondition.checkSqdsArguement(userInfo != null, "无效操作");
        model.addAttribute("userInfo", userInfo);
    }

    @MyLog(value = "用户密码初始化")
    @RequestMapping(value = "savePwd", method = RequestMethod.POST)
    @ResponseBody
    @RequiresPermissions("userInfo:savePwd")
    public Response savePwd(HttpServletRequest request) {

        String username = ParamUtils.getString(request, "username", "");
        String pwd = ParamUtils.getString(request, "pwd", "");
        pwd = Base64Utils.decode(pwd);
        UserInfo userInfo = this.userInfoService.findByUsername(username);
        Precondition.checkAjaxArguement(userInfo != null, "1111", "无效操作");

        Map<String, String> map = encipherPwd.getEncipherPwd(username, pwd);
        String encipher_password = map.get("password");
        String encipher_salt = map.get("salt");

        this.userInfoService.updatePwd(userInfo.getId(), encipher_password, encipher_salt);

        return new Response("0001", "更新成功");
    }

    @MyLog(value = "用户密码变更")
    @RequestMapping(value = "setPwd", method = RequestMethod.POST)
    @ResponseBody
    @RequiresPermissions("userInfo:setPwd")
    public Response setPwd(HttpServletRequest request) {

        String newPwd = ParamUtils.getString(request, "newPwd", "");
        String confirmPwd = ParamUtils.getString(request, "confirmPwd", "");

        Precondition.checkAjaxArguement(newPwd.equals(confirmPwd), "1111", "两次密码不一致");

        String username = ParamUtils.getString(request, "username", "");
        String oldPwd = ParamUtils.getString(request, "oldPwd", "");
        UserInfo userInfo = this.userInfoService.findByUsername(username);
        Precondition.checkAjaxArguement(userInfo != null, "1111", "无效操作");

        String credentialsPwd = encipherPwd.getCredentialsPwd(userInfo.getUsername(), oldPwd, userInfo.getSalt());
        Precondition.checkAjaxArguement(credentialsPwd.equals(userInfo.getPassword()), "1111", "原始密码输入有误");

        Map<String, String> map = encipherPwd.getEncipherPwd(username, newPwd);
        String encipher_password = map.get("password");
        String encipher_salt = map.get("salt");

        this.userInfoService.updatePwd(userInfo.getId(), encipher_password, encipher_salt);

        return new Response("0001", "更新成功");
    }

    @RequestMapping("onlineUserInfo")
    @RequiresPermissions("userInfo:onlineUserInfo")
    public void onlineUserInfo() {
    }

    @RequestMapping("onlineUserInfoJson")
    @ResponseBody
    @RequiresPermissions("userInfo:onlineUserInfoJson")
    public Map onlineUserInfoJson(ModelMap model) {
        List<Map> resultList = this.userInfoService.onlineUserList();
        return LayUiUtils.list(resultList);
    }

    /**
     * 踢出指定登录用户
     * 该方式适合用户量不太多，否则将影响性能
     *
     * @param sessionId
     * @return
     */
    @MyLog(value = "用户剔除")
    @RequestMapping("logoutOnlineUser")
    @ResponseBody
    @RequiresPermissions("userInfo:logoutOnlineUser")
    public Response logoutOnlineUser(String sessionId) {
        DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
        DefaultWebSessionManager sessionManager = (DefaultWebSessionManager) securityManager.getSessionManager();
        Collection<Session> sessions = sessionManager.getSessionDAO().getActiveSessions();//获取当前已登录的用户session列表
        if (CollectionUtils.isNotEmpty(sessions)) {
            for (Session session : sessions) {
                String id = session.getId().toString();
                if (id.equals(sessionId)) {
                    session.setTimeout(0);
                    break;
                }
            }
        }
        return new Response("0001", "已踢出");
    }
}
